/*
 * Copyright 2006-2014 conac.cn. All rights reserved.
 * Support: http://www.conac.cn
 * License: http://www.conac.cn/license
 */
package cn.conac.framework.common.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;

public class DateUtil {

	private DateUtil() {

	}

	public static final String FORMAT_HHMM = "HH:mm";
	public static final String FORMAT_MMDD = "MM-dd";
	public static final String FORMAT_YYYY = "yyyy";
	public static final String FORMAT_YYYYMMDDHHmmss = "yyyyMMddHHmmss";
	public static final String FORMAT_YYYY_CHINESE = "yyyy年";
	public static final String FORMAT_YYYYMMDD = "yyyy-MM-dd";
	public static final String FORMAT_YYYYMMDD_SHORT = "yyyyMMdd";
	public static final String FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
	public static final String FORMAT_YYYYMM_CHINESE = "yyyy年MM月";
	public static final String FORMAT_MMDD_CHINESE = "MM月dd日";
	public static final String FORMAT_YYYYMMDD_CHINESE = "yyyy年MM月dd日";
	public static final String FORMAT_FULL_CHINESE = "yyyy年MM月dd日 HH时mm分ss秒";
	public static final String[] WEEKS = { "星期日", "星期一", "星期二", "星期三", "星期四",
			"星期五", "星期六" };
	
	public static String DEFAULT_DB_TIMEZONE = "GMT+8";

	/**
	 * 得到指定时间的时间日期格式
	 * 
	 * @param date
	 *            指定的时间
	 * @param format
	 *            时间日期格式
	 * @return
	 */
	public static String getFormatDateTime(Date date, String format) {
		DateFormat df = new SimpleDateFormat(format);
		return df.format(date);
	}

	/**
	 * 判断是否是润年
	 * 
	 * @param date
	 *            指定的时间
	 * @return true:是润年,false:不是润年
	 */
	public static boolean isLeapYear(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return isLeapYear(cal.get(Calendar.YEAR));
	}

	/**
	 * 判断是否是润年
	 * 
	 * @param date
	 *            指定的年
	 * @return true:是润年,false:不是润年
	 */
	public static boolean isLeapYear(int year) {
		GregorianCalendar calendar = new GregorianCalendar();
		return calendar.isLeapYear(year);
	}

	/**
	 * 判断指定的时间是否是今天
	 * 
	 * @param date
	 *            指定的时间
	 * @return true:是今天,false:非今天
	 */
	public static boolean isInToday(Date date) {
		boolean flag = false;
		Date now = new Date();
		String fullFormat = getFormatDateTime(now, DateUtil.FORMAT_YYYYMMDD);
		String beginString = fullFormat + " 00:00:00";
		String endString = fullFormat + " 23:59:59";
		DateFormat df = new SimpleDateFormat(DateUtil.FORMAT_FULL);
		try {
			Date beginTime = df.parse(beginString);
			Date endTime = df.parse(endString);
			flag = date.before(endTime) && date.after(beginTime);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return flag;
	}

	/**
	 * 判断两时间是否是同一天
	 * 
	 * @param from
	 *            第一个时间点
	 * @param to
	 *            第二个时间点
	 * @return true:是同一天,false:非同一天
	 */
	public static boolean isSameDay(Date from, Date to) {
		boolean isSameDay = false;
		DateFormat df = new SimpleDateFormat(DateUtil.FORMAT_YYYYMMDD);
		String firstDate = df.format(from);
		String secondDate = df.format(to);
		isSameDay = firstDate.equals(secondDate);
		return isSameDay;
	}

	/**
	 * 求出指定的时间那天是星期几
	 * 
	 * @param date
	 *            指定的时间
	 * @return 星期X
	 */
	public static String getWeekString(Date date) {
		return DateUtil.WEEKS[getWeek(date) - 1];
	}

	/**
	 * 求出指定时间那天是星期几
	 * 
	 * @param date
	 *            指定的时间
	 * @return 1-7
	 */
	public static int getWeek(Date date) {
		int week = 0;
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		week = cal.get(Calendar.DAY_OF_WEEK);
		return week;
	}

	/**
	 * 取得指定时间离现在是多少时间以前，如：3秒前,2小时前等 注意：此计算方法不是精确的
	 * 
	 * @param date
	 *            已有的指定时间
	 * @return 时间段描述
	 */
	public static String getAgoTimeString(Date date) {
		Date now = new Date();
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		Date agoTime = cal.getTime();
		long mtime = now.getTime() - agoTime.getTime();
		String str = "";
		long stime = mtime / 1000;
		long minute = 60;
		long hour = 60 * 60;
		long day = 24 * 60 * 60;
		long weeks = 7 * 24 * 60 * 60;
		long months = 100 * 24 * 60 * 60;
		if (stime < minute) {
			long time_value = stime;
			if (time_value <= 0) {
				time_value = 1;
			}
			str = time_value + "秒前";
		} else if (stime >= minute && stime < hour) {
			long time_value = stime / minute;
			if (time_value <= 0) {
				time_value = 1;
			}
			str = time_value + "分前";
		} else if (stime >= hour && stime < day) {
			long time_value = stime / hour;
			if (time_value <= 0) {
				time_value = 1;
			}
			str = time_value + "小时前";
		} else if (stime >= day && stime < weeks) {
			long time_value = stime / day;
			if (time_value <= 0) {
				time_value = 1;
			}
			str = time_value + "天前";
		} else if (stime >= weeks && stime < months) {
			DateFormat df = new SimpleDateFormat(DateUtil.FORMAT_MMDD);
			str = df.format(date);
		} else {
			DateFormat df = new SimpleDateFormat(DateUtil.FORMAT_YYYYMMDD);
			str = df.format(date);
		}
		return str;
	}

	/**
	 * 判断指定时间是否是周末
	 * 
	 * @param date
	 *            指定的时间
	 * @return true:是周末,false:非周末
	 */
	public static boolean isWeeks(Date date) {
		boolean isWeek = false;
		isWeek = (getWeek(date) - 1 == 0 || getWeek(date) - 1 == 6);
		return isWeek;
	}

	/**
	 * 得到今天的最开始时间
	 * 
	 * @return 今天的最开始时间
	 */
	public static Date getTodayBeginTime() {
		String beginString = DateUtil.FORMAT_YYYYMMDD + " 00:00:00";
		DateFormat df = new SimpleDateFormat(DateUtil.FORMAT_FULL);
		Date beginTime = new Date();
		try {
			beginTime = df.parse(beginString);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return beginTime;
	}

	/**
	 * 得到今天的最后结束时间
	 * 
	 * @return 今天的最后时间
	 */
	public static Date getTodayEndTime() {
		String endString = DateUtil.FORMAT_YYYYMMDD + " 23:59:59";
		DateFormat df = new SimpleDateFormat(DateUtil.FORMAT_FULL);
		Date endTime = new Date();
		try {
			endTime = df.parse(endString);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return endTime;
	}

	/**
	 * 取得本周的开始时间
	 * 
	 * @return 本周的开始时间
	 */
	public static Date getThisWeekBeginTime() {
		Date beginTime = null;
		Calendar cal = Calendar.getInstance();
		int week = getWeek(cal.getTime());
		week = week - 1;
		int days = 0;
		if (week == 0) {
			days = 6;
		} else {
			days = week - 1;
		}
		cal.add(Calendar.DAY_OF_MONTH, -days);
		beginTime = cal.getTime();
		return beginTime;
	}

	/**
	 * 取得本周的开始日期
	 * 
	 * @param format
	 *            时间的格式
	 * @return 指定格式的本周最开始时间
	 */
	public static String getThisWeekBeginTimeString(String format) {
		DateFormat df = new SimpleDateFormat(format);
		return df.format(getThisWeekBeginTime());
	}

	/**
	 * 取得本周的结束时间
	 * 
	 * @return 本周的结束时间
	 */
	public static Date getThisWeekEndTime() {
		Date endTime = null;
		Calendar cal = Calendar.getInstance();
		int week = getWeek(cal.getTime());
		week = week - 1;
		int days = 0;
		if (week != 0) {
			days = 7 - week;
		}
		cal.add(Calendar.DAY_OF_MONTH, days);
		endTime = cal.getTime();
		return endTime;
	}

	/**
	 * 取得本周的结束日期
	 * 
	 * @param format
	 *            时间的格式
	 * @return 指定格式的本周结束时间
	 */
	public static String getThisWeekEndTimeString(String format) {
		DateFormat df = new SimpleDateFormat(format);
		return df.format(getThisWeekEndTime());
	}

	/**
	 * 取得两时间相差的天数
	 * 
	 * @param from
	 *            第一个时间
	 * @param to
	 *            第二个时间
	 * @return 相差的天数
	 */
	public static long getBetweenDays(Date from, Date to) {
		long days = 0;
		long dayTime = 24 * 60 * 60 * 1000;
		long fromTime = from.getTime();
		long toTime = to.getTime();
		long times = Math.abs(fromTime - toTime);
		days = times / dayTime;
		return days;
	}

	/**
	 * 取得两时间相差的毫秒数
	 * 
	 * @param from
	 *            第一个时间
	 * @param to
	 *            第二个时间
	 * @return 相差的毫秒数
	 */
	public static long getMillisBetweenDays(Date from, Date to) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(from);
		long f = cal.getTimeInMillis();
		cal.setTime(to);
		long t = cal.getTimeInMillis();
		return t - f;
	}

	/**
	 * 取得两时间相差的小时数
	 * 
	 * @param from
	 *            第一个时间
	 * @param to
	 *            第二个时间
	 * @return 相差的小时数
	 */
	public static long getBetweenHours(Date from, Date to) {
		long hours = 0;
		long hourTime = 60 * 60 * 1000;
		long fromTime = from.getTime();
		long toTime = to.getTime();
		long times = Math.abs(fromTime - toTime);
		hours = times / hourTime;
		return hours;
	}
	

	/**
	 * 计算两个日期之间相差的月份数
	 * <br> 日期顺序不分先后不会返回负数
	 * <br> 不足一个月算做一个月
	 * @param date1
	 * 		日期1
	 * @param date2
	 * 		日期2
	 * @return
	 * 		月数
	 */
	public static int getBetweenMonths(Date date1, Date date2){      
        int iMonth = 0;      
        Calendar objCalendarDate1 = Calendar.getInstance();      
        objCalendarDate1.setTime(date1);      
  
        Calendar objCalendarDate2 = Calendar.getInstance();      
        objCalendarDate2.setTime(date2);      
  
        if (objCalendarDate2.equals(objCalendarDate1))      
            return 0;      
        if (objCalendarDate1.after(objCalendarDate2)){      
            Calendar temp = objCalendarDate1;      
            objCalendarDate1 = objCalendarDate2;      
            objCalendarDate2 = temp;      
        }      
      
        if (objCalendarDate2.get(Calendar.YEAR) > objCalendarDate1.get(Calendar.YEAR))      
            iMonth = ((objCalendarDate2.get(Calendar.YEAR) - objCalendarDate1.get(Calendar.YEAR))      
                    * 12 + objCalendarDate2.get(Calendar.MONTH))      
                    - objCalendarDate1.get(Calendar.MONTH);      
        else     
            iMonth = objCalendarDate2.get(Calendar.MONTH)      
                    - objCalendarDate1.get(Calendar.MONTH);      
  
        return iMonth;      
    }
	
	/**
	 * 获取两个日期相差的年数
	 * @param from
	 * @param to
	 * @return
	 */
	public static int getBetweenYears(Date from, Date to){
		return getBetweenMonths(from ,to) / 12;
	}

	/**
	 * 取得在指定时间上加减days天后的时间
	 * 
	 * @param date
	 *            指定的时间
	 * @param days
	 *            天数,正为加，负为减
	 * @return 在指定时间上加减days天后的时间
	 */
	public static Date addDays(Date date, int days) {
		Date time = null;
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DAY_OF_MONTH, days);
		time = cal.getTime();
		return time;
	}

	/**
	 * 取得在指定时间上加减months月后的时间
	 * 
	 * @param date
	 *            指定时间
	 * @param months
	 *            月数，正为加，负为减
	 * @return 在指定时间上加减months月后的时间
	 */
	public static Date addMonths(Date date, int months) {
		Date time = null;
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, months);
		time = cal.getTime();
		return time;
	}

	/**
	 * 取得在指定时间上加减years年后的时间
	 * 
	 * @param date
	 *            指定时间
	 * @param years
	 *            年数，正为加，负为减
	 * @return 在指定时间上加减years年后的时间
	 */
	public static Date addYears(Date date, int years) {
		Date time = null;
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.YEAR, years);
		time = cal.getTime();
		return time;
	}

	/**
	 * 功能:
	 * 
	 * @author zhangfz
	 * @since 2012-5-9
	 * @param string
	 * @param format
	 * @return
	 */
	public static Date parseDateFormat(String string, String format) {
		DateFormat df = new SimpleDateFormat(format);
		try {
			return df.parse(string);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 功能:把UTC时间转化成GMT时间
	 * 
	 * @author wenqing
	 * @since 2014-3-19
	 * @param string
	 * @param format
	 * @return  
	 */

	public static Date parseRFC3339Date(String datestring)throws java.text.ParseException, IndexOutOfBoundsException {

		Date d = new Date();
		// if there is no time zone, we don't need to do any special parsing.
		if (datestring.endsWith("Z")) {
			try {
				SimpleDateFormat s = new SimpleDateFormat(
						"yyyy-MM-dd'T'HH:mm:ss'Z'");// spec for RFC3339
				
				//s.setTimeZone(TimeZone.getTimeZone("UTC")); 
				d = s.parse(datestring);
				
			    SimpleDateFormat localFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				localFormater.setTimeZone(TimeZone.getDefault());
				String localTime = localFormater.format(d.getTime()); 
				System.out.println(localTime);
			} catch (java.text.ParseException pe) {// try again with optional //
				
				pe.getStackTrace();
				// decimals
				SimpleDateFormat s = new SimpleDateFormat(
						"yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'");// // spec for RFC3339 // (with fractional //seconds)
				s.setLenient(true);
				d = s.parse(datestring);
		//		SimpleDateFormat localFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//		TimeZone zone = TimeZone.getTimeZone("GMT+8:00");
		//		long date=d.getTime();
		//		utcToTimeZoneDate(date,zone,localFormater);
			}
		}
		return d;
}
	
	  public static String utcToTimeZoneDate(long date, TimeZone timeZone, DateFormat format){
	        Date dateTemp = new Date(date);
	        format.setTimeZone(timeZone);
	        return format.format(dateTemp);
	  }
	

	

	public static String getSimpleDateFormat(Date d) {
		SimpleDateFormat format = new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss", Locale.CHINA);
		String result = format.format(d);
		return result;
	}
	/**
	 * 判断指定日期是否在一个时间区间内
	 * @param srcDate Date 待判断日期
	 * @param startDate 开始时间
	 * @param endDate 结束时间
	 * 
	 * @return boolean 在目标区间内 返回true 否则返回false
	 * */
	public static boolean isBetween(Date srcDate, Date startDate, Date endDate) {
		if (srcDate == null) {
			srcDate = new Date();
		}
		
		if (srcDate == null || startDate == null || endDate == null) {
			return false;
		}

		if (srcDate.getTime() > startDate.getTime() && srcDate.getTime() < endDate.getTime()) {
			return true;
		}

		return false;
	}


	public static String getUTCTime(){
		SimpleDateFormat s = new SimpleDateFormat(
				"yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'");
		s.format(new Date());
		return s.format(new Date());
	}
	
}